var OInterface = OClass({

	// hold the rules
	_rules: null,
	
	// hold the current/last check
	_currentRule: null,

	init: function(name, rules) {
	
		// store the name
		this._name = name;
	
		// store the rules
		this._rules = rules;
		
	},

	implementedBy: function(o){
		
		// if we're null or not an object, no point in checking
		if (o === null || typeof o !== "object") return false;		

		var passed = true;
		var rules = this._rules;
		objx(rules).each(function(rule, prop){
			
			// save the current rule (in case we need to report on this)
			this._currentRule = {
				prop: prop,
				rule: rule
			};
			
			if (!OCheck(OGet(o, prop), rule)) {
				passed = false;
				return false;
			}
			
		}.bind(this));
		
		return passed;
		
	},
	
	ensureImplementedBy: function() {
	
		objx(arguments).each(function(o){
				
			if (!this.implementedBy(o)) {
			
				var errorMsg = "Object doesn't correctly implement the interface " + this._name + ". ";
				var prop = this._currentRule.prop;
				var rule = this._currentRule.rule;
				
				errorMsg += "Object should have a \"" + prop + "\" property which should pass the rule";
				
				if (ODebug) {
					OConsole([errorMsg + ":", rule]);
				}
				
				OError("OInterface", errorMsg + " which has just been logged in the console.");
				
			}
			
		}.bind(this));
	
	},
	
	OClass_shouldMixin: false,
	OClass_onClassReady: function(klass){
		this.ensureImplementedBy(klass);
	}
	
});

OProvides("objx.interface");